﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace zy_simu.Data
{

    // device pre-defined infomation
    public class DevPreDef
    {
        public const byte KEY_INVALID = 0x0f;
        public const byte DISP_ITEM_INVALID = 0x07;
        public const short ref_voltage = 3300;
        public const int tem_om_table_base = 50;  // 反查温度表的基值, 一般就是表的最低值取负

        // 基于<<传感器连线（8000002941）规格书>> [-50, +105]共计156项, -40 -- 62670 om; 0 -- 6495 om; 40 -- 1071 om; 105 -- 122
        public static uint[] tem_om_table = {
            121000, 113100, 105700, 98870, 92520, 86610, 81120, 76000, 71240, 66810,
            62670, 58818, 55225, 51871, 48740, 45815, 43082, 40527, 38138, 35902,
            33810, 31851, 30016, 28296, 26684, 25172, 23754, 22424, 21175, 20002,
            18900, 17865, 16892, 15976, 15116, 14306, 13544, 12826, 12150, 11513,
            10913, 10347, 9814, 9311, 8836, 8388, 7965, 7566, 7189, 6832,
            6495, 6175, 5872, 5586, 5316, 5060, 4818, 4589, 4372, 4167,
            3973, 3788, 3614, 3448, 3291, 3142, 3000, 2866, 2738, 2617,
            2502, 2392, 2288, 2189, 2095, 2005, 1920, 1838, 1761, 1687,
            1617, 1550, 1486, 1425, 1367, 1312, 1259, 1209, 1161, 1115,
            1071, 1029, 989, 950, 914, 879, 845, 813, 783, 753,
            725, 698, 673, 648, 624, 602, 580, 559, 539, 520,
            502, 484, 467, 451, 436, 421, 406, 392, 379, 367,
            354, 343, 331, 320, 310, 300, 290, 281, 273, 264,
            256, 248, 241, 233, 226, 219, 213, 206, 200, 194,
            189, 183, 178, 173, 167, 163, 158, 154, 149, 145,
            141, 137, 133, 129, 126, 122,
        };
        // 基于<<环温传感器SDNT1005X103F3380FTF热敏R-T对照表.pdf>> [-30, +99]共计130项, -30 -- 119520 om; 0 -- 27800 om; 99 -- 990
        // public static uint[] tem_om_table = {
        //     119520, 113300, 107450, 101930, 96730, 91830, 87210, 82850, 78730, 74850,
        //     71180, 67710, 64430, 61330, 58400, 55620, 53000, 50510, 48160, 45930,
        //     43810, 41810, 39910, 38110, 36400, 34770, 33230, 31770, 30380, 29050,
        //     27800, 26600, 25460, 24380, 23350, 22370, 21440, 20550, 19700, 18900,
        //     18130, 17390, 16690, 16020, 15390, 14780, 14200, 13640, 13110, 12610,
        //     12120, 11660, 11220, 10790, 10390, 10000, 9630, 9270, 8930, 8610,
        //     8300, 8000, 7710, 7430, 7170, 6920, 6670, 6440, 6220, 6000,
        //     5800, 5600, 5410, 5230, 5050, 4880, 4720, 4570, 4420, 4270,
        //     4130, 4000, 3870, 3750, 3630, 3510, 3400, 3300, 3190, 3090,
        //     3000, 2910, 2820, 2730, 2650, 2570, 2490, 2420, 2350, 2280,
        //     2210, 2150, 2090, 2030, 1970, 1910, 1860, 1800, 1750, 1700,
        //     1660, 1610, 1570, 1520, 1480, 1440, 1400, 1370, 1330, 1290,
        //     1260, 1230, 1190, 1160, 1300, 1100, 1070, 1050, 1020, 990,
        // };

        // key definition ===================================================================================================
        public enum DispKeyIdx // same as device enum DispKeyIdx
        {
            MINUS = 0,
            PLUS,
            SET,
            LIGHT,
            POW,
            LOCK,
            TOGGLE,
            FUNC,
            SND_ALARM,
            COOL,
            FREEZE
        };
        // define virtual key description table
        public static readonly Dictionary<byte, (string, string)> KeyDescriptionTable = new Dictionary<byte, (string, string)> {
            {(byte)DispKeyIdx.MINUS, ("MINUS", "fas fa-minus")},
            {(byte)DispKeyIdx.PLUS, ("PLUS", "fas fa-plus")},
            {(byte)DispKeyIdx.SET, ("SET", "fas fa-gear")},
            {(byte)DispKeyIdx.LIGHT, ("LIGHT", "fas fa-lightbulb")},
            {(byte)DispKeyIdx.POW, ("POW", "fas fa-retweet")},
            {(byte)DispKeyIdx.LOCK, ("LOCK", "fas fa-lock")},
            {(byte)DispKeyIdx.TOGGLE, ("TOGGLE", "fas fa-repeat")},
            {(byte)DispKeyIdx.FUNC, ("FUNC", "fas fa-cloud-rain")},
            {(byte)DispKeyIdx.COOL, ("MINUS", "fas fa-minus")},
            {(byte)DispKeyIdx.FREEZE, ("PLUS", "fas fa-plus")},
            //(DispKeyIdx.KEY_SND_ALARM, "SND_ALARM", "fas fa-gear"),
        };

        // display item definition ===================================================================================================
        public enum DispItemIdx // same as device enum DispItemIdx
        {
            COMP = 0,
            HOT,
            DEFROST,
            LP,
            LOCK,
            ALARM,
            FAN,
            DOOR,
            WIFI,
            _4G,
            BATTERY,
            BT,
            DRIP,
            POW,
            RES1,
            RES2,
            DOT,
            MINUS,
            D1,       // 千
            D2,       // 百
            D3,       // 十
            D4,       // 个
            ALL_NUM,  // all display items number, must be the even
            ICON_NUM = D1,
            DIGITAL_NUM = ALL_NUM - ICON_NUM,
            INVALID = ALL_NUM,
        };
        // define icon description table
        public static readonly List<(DispItemIdx, string, string)> IconDescriptionTable = new([
            (DispItemIdx.COMP, "压机灯", "fas fa-snowflake"),
            (DispItemIdx.HOT, "制热灯", "fas fa-mug-hot"),
            (DispItemIdx.DEFROST, "化霜灯", "fas fa-cloud-rain"),
            (DispItemIdx.LP, "节能灯", "fas fa-leaf"),
            (DispItemIdx.LOCK, "锁屏灯", "fas fa-lock"),
            (DispItemIdx.ALARM, "报警灯", "fas fa-circle-exclamation"),
            (DispItemIdx.FAN, "风机灯", "fas fa-fan"),
            (DispItemIdx.DOOR, "门1灯", "fas fa-door-open"),
            (DispItemIdx.WIFI, "WIFI灯", "fas fa-wifi"),
            (DispItemIdx._4G, "4G灯", "fas fa-signal"),
            (DispItemIdx.BATTERY, "电池灯", "fas fa-battery-three-quarters"),
            (DispItemIdx.BT, "蓝牙灯", "fas fa-satellite-dish"),
            (DispItemIdx.DRIP, "滴水灯", "fas fa-faucet-drip"),
            (DispItemIdx.POW, "电源灯", "fas fa-power-off"),
            (DispItemIdx.RES1, "冷藏", "fas fa-regular fa-temperature-high"),
            (DispItemIdx.RES2, "冷冻", "fas fa-regular fa-temperature-low"),
            (DispItemIdx.DOT, "小数点", "fas fa-circle"),
            (DispItemIdx.MINUS, "负号", "fas fa-circle"),
        ]);
        public class DispItemCodecTb
        {
            public DispItemCodecTb()
            {
                data = DISP_ITEM_INVALID;
            }

            public byte data;
            public byte grid
            {
                get => (byte)(data & 0x0f);
                set => data = (byte)((data & 0xf0) | (value & 0x0f));
            }
            public byte seg
            {
                get => (byte)((data & 0xf0) >> 4);
                set => data = (byte)((data & 0x0f) | ((value & 0x0f) << 4));
            }
        };

        // parametwes definition table ===================================================================================================
        // 设备参数描述集合
        public static readonly Dictionary<string, string> pms_des = new()
        {
            {"NA", "NA"},
            {"TS", "温度设定值, ℃"},
            {"r1", "温度设定最小值, ℃"},
            {"r2", "温度设定最大值, ℃"},
            {"Ad", "温度报警延迟, min"},
            {"C1", "温度上回差, .1℃"},
            {"C2", "温度下回差, .1℃"},
            {"C3", "传感器故障开机, min"},
            {"C4", "传感器故障关机, min"},
            {"C5", "显示温度补偿, .1℃"},
            {"C6", "化霜解锁时间, hour"},
            {"C7", "最短停机时间, min"},
            {"C8", "开停机补偿, ℃"},

            {"d1", "自然化霜/压机保护周期, hour"},
            {"d2", "自然化霜/压机保护时间, min"},
            {"d3", "自然化霜/压机保护周期, hour"},
            {"d4", "自然化霜/压机保护时间, min" },
            {"F1", "故障代码" },
            {"F2", "4G信号强度" },
            {"F3", "电池电量 %" },
            {"F4", "软件版本" },
            {"F5", "高温报警温度, ℃"},
            {"F6", "低温报警温度, ℃"},
            {"b1", "温度上回差, .1℃"},
            {"b2", "温度下回差, .1℃"},
            {"b3", "传感器故障开机, min"},
            {"b4", "传感器故障关机, min"},
            {"b5", "显示温度补偿, .1℃"},
            {"b6", "化霜解锁时间, hour"},
            {"b7", "最短停机时间, min"},
            {"b8", "开停机补偿, ℃"},

            {"PS", "密码配置"},
            {"AS", "上电报警延时, hour"},

            {"cd", "压缩机上电后的延时, 分钟" },
            {"cf", "压机强制运行, hour" },
            {"mtc", "测量温度补偿, .1℃" },

            {"d3_", "热除霜周期, hour"},
            {"d4_", "除霜排水时间, min"},
            {"d5", "热除霜预冷时间(m)/首上电化霜延迟(h)"},
            {"d6", "热除霜退出温度, ℃"},
            {"d7", "热除霜上限时间, min"},
            {"d8", "强制除霜, min"},
            {"dtt", "化霜计时方式" },

            {"h4", "蜂鸣器开关"},
            {"dm", "显示模式"},
            {"hs", "手动化霜"},
            {"lc","拉温模式"},

            {"f7", "非营业模块开始时间, H"},
            {"f8", "非营业模块结束时间, H"},
            {"f9", "非营业模块智能模式, N"},
            {"tr", "非营业模式设定温度, ℃"},
            {"F10", "冷凝风机转速调节" },

            {"smp", "采样周期, h" },
            {"rpt", "上报周期, h"},
        };

        // 设备状态描述
        public static readonly string[] st_name = 
        {
            "d_temp", 
            "m_temp", 
            "load_vol", 
            "load_cur", 
            "load_pow", 
            "vbat", 
            
            "alarm",
            "fan_state", 
            "light_state", 
            "heater_state", 
            
            "ble", 
            "_4g", 
            "wifi", 
            "_4g_strength",
            
            "ctrl_mode", 
            "ctrl_state", 
            "ctrl_switch",

            "comp_mode", 
            "comp_state", 
            "temp_reach_region", 
            "power_up_6h", 

            "comp_on_timer", 
            "comp_on_timer_acc", 
            "comp_off_timer", 
            "sensor_fault_on", 
            "sensor_fault_off", 
            "comp_cc",

            "defrost_timer", 
            "defrost_d_temp", 
            "defrost_m_temp", 
            "defrost_drain_timer", 
            "defrost_lock_timer", 
            
            "humman", "alarm_ad_timer", "cat1_heart",

            "d1_count", "d2_count", "d1_open_ms", "d2_open_ms", "d1_all_open_s", "d2_all_open_s", "smp_idx",
        };

        public static readonly string[] st_des =
        {
            "显示温度",
            "测量温度",
            "负载电压",
            "负载电流",
            "负载功率",
            "电池电压 mv",

            "报警项目",
            "风机工作状态",
            "照明灯状态",
            "加热器启停状态",

            "蓝牙工作状态",
            "4G ",
            "wifi",
            "4G信号强度",

            "控制器工作模式",
            "控制器工作状态",
            "控制器开关",

            "压机运行模式",
            "压机运行状态",
            "温度到达过TS+-2区间",
            "开机到达6小时",

            "压机本次运行时间",
            "压机累计运行时间",
            "压机关机时间",
            "故障开机时间",
            "故障关机时间",
            "强制开机时间",

            "除霜运行时间",
            "除霜传感器显示温度",
            "除霜传感器测量温度",
            "除霜排水时间",
            "除霜后温度锁定计时",

            "人流量计数",
            "温度报警延迟计时",
            "Cat1心跳计时追踪",

            "门1开关门次数,",
            "门2/防拆开关门次数,",
            "门1本次开门计时ms",
            "门2/防拆本次开门计时ms",
            "门1累计开门时间s",
            "门2/防拆累计开门时间s",
            "采样计数",

    };

        public const int ADC_CHN_NTC1 = 0;
        public const int ADC_CHN_NTC2 = 1;
        public const int ADC_CHN_VBAT = 2;
        public const int ADC_CHN_VREF = 3;
    }



    // 设备数据结构体预定义 =========================================================================================================
    // display mode record

    // 设备状态描述 - 状态结构
    // 成员必须加public, 不然和dll交互出错
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public class ZyStates
    {
        // 温度state
        public short d_temp;                // 显示温度
        public short m_temp;                // 测量温度
        public short load_vol;              // 负载电压
        public short load_cur;              // 负载电流
        public short load_pow;              // 负载功率
        public short vbat;                  // 电池电压 mv, 0 - 4200, =NUM_INVALID_WORD 表示无电池

        public byte alarm;				    // 报警
        public byte fan_state;              // 风机工作状态
        public byte light_state;		    // 照明灯状态
        public byte heater_state;           // 加热器启停状态

        public byte ble;                    // 蓝牙工作状态
        public byte _4g;                    // "4G ",
        public byte wifi;                   // "wifi",
        public byte _4g_strength;           // "4G信号强度",
        // 控制器state
        public byte ctrl_mode;              // 控制器工作模式: 1 - 冷藏, 2 - 冷冻, 3 - 加热, 4 - 节能?
        public byte ctrl_state;             // 控制器当前实际工作状态: 0-关闭, 1-开启
        public byte ctrl_switch;            // 控制器开关
        // 压机state
        public byte comp_mode;              // 压机运行模式, 参见enum ZyCompMode, 可能多个mode组合，但是当前实际按优先级运行
        public byte comp_state;             // 压机启停状态, 真实状态还要参见mode, 比如压机保护模式下, state=1, 并没有启动压机, 只是闪灯.
        public byte temp_reach_region;      // 温度到过达TS+-2区间
        public ushort power_up_6h;		    // 上电6小时计时

        public int comp_on_timer;           // 压机本次运行时间
        public int comp_on_timer_acc;       // 压机累计运行时间
        public int comp_off_timer;          // 压机持续关机时间
        public int sensor_fault_on;        // 故障制冷开机时间 c3
        public int sensor_fault_off;       // 故障制冷关机时间 c4
        public int comp_cc;		            // 强制开机时间
        // 除霜state
        //public int defrost_state;           // 除霜工作状态
        public int defrost_timer;           // 除霜运行时间
        public short defrost_d_temp;        // 除霜传感器显示温度
        public short defrost_m_temp; 		// 除霜传感器测量温度
        public int defrost_drain_timer;	    // 除霜排水时间
        public int defrost_lock_timer;      // 除霜后温度锁定计时


        public int humman;                  // 人流量计数
        // 温度报警延迟计时 min
        public int alarm_ad_timer;
        // cat1 心跳计时
        public int cat1_heart;

        public short d1_count;      // 采样周期内门1累计开门次数,
        public short d2_count;      // 采样周期内门1累计开门次数,
        public int d1_open_ms;      // 门1本次开门计时ms, mx = 24.8day, also is door position state, =0 -- close
        public int d2_open_ms;      // 门1本次开门计时ms, mx = 24.8day, also is door position state, =0 -- close
        public int d1_all_open_s;   // 采样周期内门1累计开门时间s,
        public int d2_all_open_s;   // 采样周期内门1累计开门时间s,
        public byte smp_idx;        // sample index

        //public ZyStates()
        //{

        //}
    };
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public class ZqmParamsTable
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
        //public char[] name = new char[4];
        public string name;
        public short val;
        public short min;
        public short max;
        public byte unit;
        public byte map;

    }

    public enum ZqAlarmFlag         // 报警标志
    {
        ZQ_ALARM_SENSOR = 0x01,         // 温度传感器错误报警, 0 = 无报警， 1 = 报警
        ZQ_ALARM_HUMIDITY = 0x02,       // 湿度传感器错误报警, 0 = 无报警， 1 = 报警
        ZQ_ALARM_H = 0X04,              // 高温报警, 0 = 无报警， 1 = 报警
        ZQ_ALARM_L = 0X08,              // 低温报警, 0 = 无报警， 1 = 报警
        ZQ_ALARM_POW = 0X10,            // 断电报警, 0 = 无报警， 1 = 报警
        ZQ_ALARM_VBAT_LOW = 0X20,       // 电池电压低报警, 0 = 无报警， 1 = 报警
        ZQ_ALARM_DOOR_OPEN = 0X40,      // 门开报警, 0 = 无报警， 1 = 报警
        ZQ_ALARM_DEFROST_SENSOR = 0X80,	// 化霜传感器错误报警, 0 = 无报警， 1 = 报警
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class DiagRespCfg
    {
        public byte data;

        public byte simu_in // 3bit countdown to 0, if not 0, will use simulator send value to simu input info, include IO, ADC, KEY, eg.
        {
            get { return (byte)(data & 0x07); }
            set { data = (byte)((data & ~0x07) | (value & 0x07)); }
        }
        public byte log     // 1: enable send log to simulator, or 0: send log with debug uart2 - 辅助和simulator联合调试用
        {
            get { return (byte)((data & 0x08) >> 3); }
            set { data = (byte)((data & ~0x08) | ((value << 3) & 0x08)); }
        }
        public byte pm      // 1: force to query all pm value, 0: query only changes 
        {
            get { return (byte)((data & 0x10) >> 4); }
            set { data = (byte)((data & ~0x10) | ((value << 4) & 0x10)); }
        }
        public byte st      // 1: force to query all state value, 0: query only changes
        {
            get { return (byte)((data & 0x20) >> 5); }
            set { data = (byte)((data & ~0x20) | ((value << 5) & 0x20)); }
        }
        public byte disp      // 1: query disp state(for macro action result check) and memory, 0: query only memory
        {
            get { return (byte)((data & 0x40) >> 6); }
            set { data = (byte)((data & ~0x40) | ((value << 6) & 0x40)); }
        }
    }

    public enum DiagCommExFlag  // diagnostic commnucation package extra flag
    {
        //pm = 0x01,      // format: n[1]+n*(idx[1]+val[2])
        //st = 0x02,      // format: n[1]+n*(idx[1]+val[4])
        io = 0x04,      // format: io_num/8*val[1]
        adc = 0x08,     // format: adc_chn_num*val[2]
        key = 0x10,     // format: key_num*val[2]
        icon = 0x20,    // format: n[1]+n*(idx[1:5]+mode[1:3])
        digital = 0x40, // format: digital_num*(val[1]+mode[1])
        timer = 0x80,   // format: val[4]
    }

    public enum DispItemMode
    {
        off,              // off
        on,               // light
        flash_05,         // 0.5Hz flash
        flash_1,          // 1Hz flash
        invalid = 0x07,   // led invalid
    }
    
    
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class ZqmIOTable
    {
        public byte periph_pow;    // 外设和ADC电源控制
        public byte cat1_en;       // cat1(通讯模块)en控制脚 - 实际控制供电
        public byte cat1_key;      // cat1(通讯模块)key控制脚 - 实际控制通讯模块开关
        public byte motor;         // 压机控制脚
        public byte fan;           // 蒸发风机控制脚
        public byte condenser_fan; // 冷凝风机控制脚
        public byte heater;        // 制热控制脚
        public byte light;         // 照明控制脚
        public byte melt;          // 化霜加热/电磁阀控制脚
        public byte buzzor;        // 蜂鸣器
        public byte det_12v;       // 电源侦测脚
        public byte det_sys_switch; // 系统开关侦测脚
        public byte det_door1;     // 门1侦测脚
        public byte det_door2;     // 门2侦测脚; or Anti-demolition detection
        public byte det_human;     // 红外人流侦测脚
        public byte batt_chrg;     // 电池侦测/充电脚
        public byte batt_stdby;     // 电池待机脚
        public byte power_led;     // 电源指示灯
        public byte adc_vref;      // adc vref	

        public byte uart0_tx;      // UART0 TX
        public byte uart0_rx;      // UART0 RX
        public byte uart1_tx;      // UART1 TX
        public byte uart1_rx;      // UART1 RX
        public byte uart2_tx;      // UART2 TX
        public byte uart2_rx;      // UART3 RX
        public byte uart3_tx;      // UART3 TX
        public byte uart3_rx;      // UART3 RX
        public byte dis_dio;       // 显示驱动spi数据线
        public byte dis_clk;       // 显示驱动模拟spi时钟线
        public byte dis_stb;       // 显示驱动使能脚
        public byte ntc1_adc;      // 传感器1
        public byte ntc2_adc;      // 传感器2
        public byte batt_adc;      // 电池电压侦测脚
        public byte pwm1;          // PWM1
        public byte pwm2;          // PWM2
    };


}
